#include <stdio.h>
#include <inttypes.h>
#include "keyboard_hook.h"


static KeyEventCallback g_callback = NULL;

// 事件分发回调函数
void dispatch_proc(uiohook_event *const event) {
    switch (event->type) {
        case EVENT_KEY_PRESSED:
            if (g_callback != NULL) {
                g_callback(event->data.keyboard.keycode, event->data.keyboard.rawcode, 1);
            }
            break;
        case EVENT_KEY_RELEASED:
            // printf("keycode=%u,rawcode=0x%X\n", event->data.keyboard.keycode, event->data.keyboard.rawcode);
            if (g_callback != NULL) {
                g_callback(event->data.keyboard.keycode, event->data.keyboard.rawcode, 2);
            }
            break;
        case EVENT_KEY_TYPED:
            // printf("keychar=%lc,rawcode=%u\n", (wint_t) event->data.keyboard.keychar, event->data.keyboard.rawcode);
            if (g_callback != NULL) {
                g_callback(event->data.keyboard.keycode, event->data.keyboard.rawcode, 3);
            }
            break;
        case EVENT_MOUSE_PRESSED:
        case EVENT_MOUSE_RELEASED:
        case EVENT_MOUSE_CLICKED:
        case EVENT_MOUSE_MOVED:
        case EVENT_MOUSE_DRAGGED:
        case EVENT_MOUSE_WHEEL:
        default:
            break;
    }
}


int InstallHook(KeyEventCallback callback) {
    g_callback = callback;
    hook_set_dispatch_proc(&dispatch_proc);

    // 启动钩子
    int status = hook_run();

    switch (status) {
        case UIOHOOK_SUCCESS:
            printf("Hook exited successfully.\n");
            break;

        case UIOHOOK_ERROR_OUT_OF_MEMORY:
            printf("Failed to allocate memory.\n");
            break;

        case UIOHOOK_ERROR_SET_WINDOWS_HOOK_EX:
            printf("Failed to register windows hook.\n");
            break;

        default:
            printf("An unknown hook error occurred.\n");
            break;
    }

    return status;
}
